package com.sky.business.sys.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sky.business.sys.domain.MediaServer;
import com.sky.business.sys.service.ZlmClientService;
import com.sky.common.exception.ZlmApiCallException;
import com.sky.common.http.HttpDecorate;
import com.sky.common.http.HttpDecorateBuilder;
import com.sky.common.zlm.param.StreamProxyOption;
import com.sky.common.zlm.resp.*;
import com.sky.common.utils.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.message.BasicNameValuePair;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.SimpleTimeZone;

/**
 * zlm接口实现类
 */
public class ZlmClientServiceImpl implements ZlmClientService {

    /**
     * http客户端
     */
    public static HttpDecorate httpDecorator = HttpDecorateBuilder.create().pool(10, 5).disableCookieManagement().build();

    /**
     * json对象映射
     */
    public static ObjectMapper objectMapper = new ObjectMapper().setTimeZone(SimpleTimeZone.getTimeZone("GMT+8"));

    /**
     * 获取http的接口url
     *
     * @param mediaServer 流媒体服务器配置信息
     * @param path        路径
     * @return 接口url
     */
    public String getHttpUrl(MediaServer mediaServer, String path) {
        return "http://" + mediaServer.getServerIp() + ":" + mediaServer.getHttpPort() + path;
    }


    @Override
    public List<ThreadLoad> getThreadsLoad(MediaServer mediaServer) {
        try {
            String url = getHttpUrl(mediaServer, "/index/api/getThreadsLoad");
            List<NameValuePair> params = new ArrayList<>();
            params.add(new BasicNameValuePair("secret", mediaServer.getApiSecret()));
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(params, "UTF-8");
            HttpUriRequest request = RequestBuilder.post().setEntity(formEntity).addHeader("Content-Type", "application/x-www-form-urlencoded").setUri(url).build();
            String json = httpDecorator.execute(request).result().string();
            ThreadLoadBaseResponse threadLoadBaseResponse =objectMapper.readValue(json, ThreadLoadBaseResponse.class);
            if (threadLoadBaseResponse.getCode() != 0) {
                throw new ZlmApiCallException(threadLoadBaseResponse.getMsg());
            }
            return threadLoadBaseResponse.getThreadLoadList();
        } catch (IOException e) {
            throw new ZlmApiCallException(e);
        }
    }

    @Override
    public List<MediaStreamInfo> getMediaList(MediaServer mediaServer, String schema, String appName, String streamName) {
        try {
            String url = getHttpUrl(mediaServer, "/index/api/getMediaList");
            List<NameValuePair> params = new ArrayList<>();
            params.add(new BasicNameValuePair("secret", mediaServer.getApiSecret()));
            if (StringUtils.isNotEmpty(schema)) {
                params.add(new BasicNameValuePair("schema", schema));
            }
            params.add(new BasicNameValuePair("vhost", mediaServer.getVhost()));
            if (StringUtils.isNotEmpty(appName)) {
                params.add(new BasicNameValuePair("app", appName));
            }
            if (StringUtils.isNotEmpty(streamName)) {
                params.add(new BasicNameValuePair("stream", streamName));
            }
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(params, "UTF-8");
            HttpUriRequest request = RequestBuilder.post().setEntity(formEntity).addHeader("Content-Type", "application/x-www-form-urlencoded").setUri(url).build();
            String json = httpDecorator.execute(request).result().string();
            MediaListResponse  mediaListResponse =objectMapper.readValue(json, MediaListResponse.class);
            return mediaListResponse.getMediaStreamInfoList();
        } catch (IOException e) {
            throw new ZlmApiCallException(e);
        }
    }

    @Override
    public List<MediaStreamInfo> getAllMediaList(MediaServer mediaServer) {
        return getMediaList(mediaServer, null, null, null);
    }

    @Override
    public String addStreamProxy(MediaServer mediaServer,String appName,String streamName, StreamProxyOption streamProxyOption) {
        try {
            String addStreamProxyUrl = getHttpUrl(mediaServer, "/index/api/addStreamProxy");
            List<NameValuePair> params = new ArrayList<>();
            params.add(new BasicNameValuePair("secret", mediaServer.getApiSecret()));
            params.add(new BasicNameValuePair("vhost", mediaServer.getVhost()));
            params.add(new BasicNameValuePair("app", appName));
            params.add(new BasicNameValuePair("stream", streamName));
            params.add(new BasicNameValuePair("url", streamProxyOption.getUrl()));
            params.add(new BasicNameValuePair("rtp_type", String.valueOf(streamProxyOption.getRtpType())));
            params.add(new BasicNameValuePair("retry_count", String.valueOf(streamProxyOption.getRetryCount())));
            params.add(new BasicNameValuePair("timeout_sec", String.valueOf(streamProxyOption.getTimeoutSec())));
            params.add(new BasicNameValuePair("enable_hls", String.valueOf(streamProxyOption.isEnableHls())));
            params.add(new BasicNameValuePair("enable_hls_fmp4", String.valueOf(streamProxyOption.isEnableHlsFmp4())));
            params.add(new BasicNameValuePair("enable_mp4", String.valueOf(streamProxyOption.isEnableMp4())));
            params.add(new BasicNameValuePair("enable_rtsp", String.valueOf(streamProxyOption.isEnableRtsp())));
            params.add(new BasicNameValuePair("enable_rtmp", String.valueOf(streamProxyOption.isEnableRtmp())));
            params.add(new BasicNameValuePair("enable_ts", String.valueOf(streamProxyOption.isEnableTs())));
            params.add(new BasicNameValuePair("enable_fmp4", String.valueOf(streamProxyOption.isEnableFmp4())));
            params.add(new BasicNameValuePair("hlsDemand", String.valueOf(streamProxyOption.isHlsDemand())));
            params.add(new BasicNameValuePair("rtspDemand", String.valueOf(streamProxyOption.isRtspDemand())));
            params.add(new BasicNameValuePair("rtmpDemand", String.valueOf(streamProxyOption.isRtmpDemand())));
            params.add(new BasicNameValuePair("tsDemand", String.valueOf(streamProxyOption.isTsDemand())));
            params.add(new BasicNameValuePair("fmp4Demand", String.valueOf(streamProxyOption.isFmp4Demand())));
            params.add(new BasicNameValuePair("autoClose", String.valueOf(streamProxyOption.isAutoClose())));
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(params, "UTF-8");
            HttpUriRequest request = RequestBuilder.post().setEntity(formEntity)
                    .addHeader("Content-Type", "application/x-www-form-urlencoded")
                    .setUri(addStreamProxyUrl).build();
            String json = httpDecorator.execute(request).result().string();
            JsonNode jsonNode = objectMapper.readTree(json);
            int code = jsonNode.get("code").asInt();
            if(code!=0){
                String msg = jsonNode.get("msg").asText();
                throw new ZlmApiCallException(msg);
            }
            JsonNode data =  jsonNode.get("data");
            return data.get("key").asText();
        }catch (IOException e){
            throw new ZlmApiCallException(e);
        }
    }

    @Override
    public boolean delStreamProxy(MediaServer mediaServer, String key) {
        try {
            String url = getHttpUrl(mediaServer, "/index/api/delStreamProxy");
            List<NameValuePair> params = new ArrayList<>();
            params.add(new BasicNameValuePair("secret", mediaServer.getApiSecret()));
            params.add(new BasicNameValuePair("key",key));
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(params, "UTF-8");
            HttpUriRequest request = RequestBuilder.post().setEntity(formEntity).addHeader("Content-Type", "application/x-www-form-urlencoded").setUri(url).build();
            String json = httpDecorator.execute(request).result().string();
            JsonNode jsonNode = objectMapper.readTree(json);
            int code = jsonNode.get("code").asInt();
            if(code!=0){
                String msg = jsonNode.get("msg").asText();
                throw new ZlmApiCallException(msg);
            }
            JsonNode data = jsonNode.get("data");
            return data.get("flag").asBoolean();
        } catch (IOException e) {
            throw new ZlmApiCallException(e);
        }
    }

    @Override
    public String addStreamPusherProxy(MediaServer mediaServer, String schema, String appName, String streamName, String dstUrl, int retryCount, int rtpType,int timeoutSec) {
        try {
            String addStreamProxyUrl = getHttpUrl(mediaServer, "/index/api/addStreamPusherProxy");
            List<NameValuePair> params = new ArrayList<>();
            params.add(new BasicNameValuePair("secret", mediaServer.getApiSecret()));
            params.add(new BasicNameValuePair("vhost",mediaServer.getVhost()));
            params.add(new BasicNameValuePair("schema",schema));
            params.add(new BasicNameValuePair("app", appName));
            params.add(new BasicNameValuePair("stream", streamName));
            params.add(new BasicNameValuePair("dst_url", dstUrl));
            params.add(new BasicNameValuePair("retry_count", String.valueOf(retryCount)));
            params.add(new BasicNameValuePair("rtp_type", String.valueOf(rtpType)));
            params.add(new BasicNameValuePair("timeout_sec", String.valueOf(timeoutSec)));
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(params, "UTF-8");
            HttpUriRequest request = RequestBuilder.post().setEntity(formEntity)
                    .addHeader("Content-Type", "application/x-www-form-urlencoded")
                    .setUri(addStreamProxyUrl).build();
            String json = httpDecorator.execute(request).result().string();
            JsonNode jsonNode = objectMapper.readTree(json);
            int code = jsonNode.get("code").asInt();
            if(code!=0){
                String msg = jsonNode.get("msg").asText();
                throw new ZlmApiCallException(msg);
            }
            JsonNode data =  jsonNode.get("data");
            return data.get("key").asText();
        }catch (IOException e){
            throw new ZlmApiCallException(e);
        }
    }

    @Override
    public boolean delStreamPusherProxy(MediaServer mediaServer, String key) {
        try {
            String url = getHttpUrl(mediaServer, "/index/api/delStreamPusherProxy");
            List<NameValuePair> params = new ArrayList<>();
            params.add(new BasicNameValuePair("secret", mediaServer.getApiSecret()));
            params.add(new BasicNameValuePair("key",key));
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(params, "UTF-8");
            HttpUriRequest request = RequestBuilder.post().setEntity(formEntity).addHeader("Content-Type", "application/x-www-form-urlencoded").setUri(url).build();
            String json = httpDecorator.execute(request).result().string();
            JsonNode jsonNode = objectMapper.readTree(json);
            int code = jsonNode.get("code").asInt();
            if(code!=0){
                String msg = jsonNode.get("msg").asText();
                throw new ZlmApiCallException(msg);
            }
            JsonNode data = jsonNode.get("data");
            return data.get("flag").asBoolean();
        } catch (IOException e) {
            throw new ZlmApiCallException(e);
        }
    }


    public static void main(String[] args) throws JsonProcessingException {
        MediaServer mediaServer = new MediaServer();
        mediaServer.setServerIp("172.22.2.235");
//        mediaServer.setServerIp("172.20.6.25");
        mediaServer.setHttpPort(80);
        mediaServer.setVhost("__defaultVhost__");
        mediaServer.setApiSecret("9Mqat287ug5bxQD6I7gKpueas2S9m82P");
//        mediaServer.setApiSecret("AixJXt2anOsCMsY0F8eTDM8Q95fib7Xo");
        ZlmClientService zlmClientService =  new ZlmClientServiceImpl();


//        List<ThreadLoad> threadLoadList = zlmClientService.getThreadsLoad(mediaServer);

//        List<MediaStreamInfo> mediaStreamInfoList = zlmClientService.getAllMediaList(mediaServer);
//        List<MediaStreamInfo> mediaStreamInfoList = zlmClientService.getMediaList(mediaServer,"rtsp","","14218415137302460512108915000139");
//        for(MediaStreamInfo mediaStreamInfo:mediaStreamInfoList){
//            System.out.println(mediaStreamInfo);
//            System.out.println("==============================");
//        }

//        StreamProxyOption streamProxyOption = StreamProxyOption.withUrl("rtsp://172.20.6.211/live/VideoChannel1").enableRtsp().withRetryCount(-1).withTimeoutSec(10).withRtpType(0);
//        String key = zlmClientService.addStreamProxy(mediaServer,"live","1",streamProxyOption);

//        boolean success = zlmClientService.delStreamProxy(mediaServer,"__defaultVhost__/live/1");

//        String key = zlmClientService.addStreamPusherProxy(mediaServer,"rtsp","live","1","rtsp://172.20.6.25/live/test1",-1,0,10);

        boolean success =  zlmClientService.delStreamPusherProxy(mediaServer,"rtsp/__defaultVhost__/live/1/14e77a6037574ade3083d5388506d142");
        System.out.println(success);

    }
}
